package model

import (
	"time"

	"bmember/pkg/db/pgex"

	"bmember/pkg/util"
)

// AccountGroup 账号体系（会员计划）
type AccountGroup struct {
	Id          int64           `json:"id" sql:"id"`
	BrandId     int64           `json:"brand_id" sql:"brand_id"`           // 品牌id
	Name        string          `json:"name" sql:"name"`                   // 体系名（会员计划）
	IsAllStores bool            `json:"is_all_stores" sql:"is_all_stores"` // 是否适用所有门店
	StoreIds    pgex.Int64Array `json:"store_ids" sql:"store_ids"`         // 指定门店id列表
	EditorId    int64           `json:"editor_id" sql:"editor_id"`         // 修改者id
	CreatedAt   time.Time       `json:"created_at" sql:"created_at"`
	UpdatedAt   time.Time       `json:"updated_at" sql:"updated_at"`
	DeletedAt   int64           `json:"deleted_at" sql:"deleted_at"`
}

// IsValid 是否有效
func (a *AccountGroup) IsValid() bool {
	return a.DeletedAt == 0
}

// NewAccountGroup 新建会员计划
func NewAccountGroup(brandId int64, name string, editorId int64) *AccountGroup {
	if name == "" {
		name = "会员计划"
	}
	now := util.GetNow()
	return &AccountGroup{
		BrandId:     brandId,
		Name:        name,
		IsAllStores: true,
		StoreIds:    []int64{},
		EditorId:    editorId,
		CreatedAt:   now,
		UpdatedAt:   now,
	}
}

// Update 更新信息
func (a *AccountGroup) Update(name string, editorId int64) {
	if name != "" {
		a.Name = name
	}
	if editorId != 0 {
		a.EditorId = editorId
	}
	a.UpdatedAt = util.GetNow()
}

// SetStores 设置体系适用门店
func (a *AccountGroup) SetStores(allStore bool, storeIds []int64) {
	a.IsAllStores = allStore
	if allStore {
		a.StoreIds = []int64{}
	} else {
		a.StoreIds = storeIds
	}
	a.UpdatedAt = util.GetNow()
}

// GetStores 获取适用门店id列表
func (a *AccountGroup) GetStores() []int64 {
	return a.StoreIds
}

// CanUseInStore 门店是否可以使用
func (a *AccountGroup) CanUseInStore(storeId int64) bool {
	if storeId == 0 {
		return true
	}
	if !a.IsAllStores {
		return util.ContainInt64(a.GetStores(), storeId)
	}
	return true
}

// 卡定义
const (
	// CardNormal 普通卡
	CardNormal int8 = 1
	// CardPaid 付费卡
	CardPaid int8 = 2

	CardNormalStr = "normal"
	CardPaidStr   = "paid"

	// 可使用
	CardStatusOK int8 = 1
	// CardStatusStopUsing 停止发卡
	CardStatusStopUsing int8 = 2
)

// CardRule 卡规则
type CardRule struct {
	Discount        uint32 `json:"discount"`          // 等级折扣
	UnitIntegralAmt uint64 `json:"unit_integral_amt"` // 1积分需要金额
	TopupLimit      uint64 `json:"topup_limit"`       // 起充金额
}

// AccountCard 账号卡定义
type AccountCard struct {
	Id          int64  `json:"id" sql:"id"`
	BrandId     int64  `json:"brand_id" sql:"brand_id"`         // 品牌id
	GroupId     int64  `json:"group_id" sql:"group_id"`         // 体系id
	Name        string `json:"name" sql:"name"`                 // 等级名
	CardType    int8   `json:"card_type" sql:"card_type"`       // 卡类型
	Cover       string `json:"cover" sql:"cover"`               // 封面
	IsDefault   bool   `json:"is_default" sql:"is_default"`     // 是否是该体系下默认卡
	CanIntegral bool   `json:"can_integral" sql:"can_integral"` // 是否可积分
	CanRecharge bool   `json:"can_recharge" sql:"can_recharge"` // 是否可充值
	Rule        []byte `json:"rule" sql:"rule"`                 // 等级设置规则
	rule        *CardRule
	Deposit     uint64    `json:"deposit" sql:"deposit"`     // 押金
	Status      int8      `json:"status" sql:"status"`       // 状态：1~正常 2~停用
	EditorId    int64     `json:"editor_id" sql:"editor_id"` // 修改者id
	CreatedAt   time.Time `json:"created_at" sql:"created_at"`
	UpdatedAt   time.Time `json:"updated_at" sql:"updated_at"`
	DeletedAt   int64     `json:"deleted_at" sql:"deleted_at"`
}

// NewAccountCard new card
func NewAccountCard(brandId, groupId int64, cardType int8, name, cover string, creator int64) *AccountCard {
	now := util.GetNow()
	return &AccountCard{
		BrandId:   brandId,
		GroupId:   groupId,
		Name:      name,
		CardType:  cardType,
		Cover:     cover,
		Deposit:   0,
		Status:    CardStatusOK,
		Rule:      []byte("{}"),
		EditorId:  creator,
		CreatedAt: now,
		UpdatedAt: now,
	}
}

// GetInnerCardType 卡类型转换
func GetInnerCardType(t string) int8 {
	switch t {
	case CardNormalStr:
		return CardNormal
	case CardPaidStr:
		return CardPaid
	default:
		return CardNormal
	}
}

// GetCardType 获取卡类型
func (a *AccountCard) GetCardType() string {
	switch a.CardType {
	case CardNormal:
		return CardNormalStr
	case CardPaid:
		return CardPaidStr
	default:
		return ""
	}
}

// IsValid 是否有效
func (a *AccountCard) IsValid() bool {
	return a.Status == CardStatusOK && a.DeletedAt == 0
}

// SetAsDefault 设置为默认卡
func (a *AccountCard) SetAsDefault() {
	a.Status = CardStatusOK
	a.IsDefault = true
}

// GetRule 获取卡规则
func (a *AccountCard) GetRule() *CardRule {
	if a.rule == nil {
		a.rule = &CardRule{}
		if a.Rule != nil {
			_ = json.Unmarshal(a.Rule, a.rule)
		}
	}
	return a.rule
}

func (a *AccountCard) setRule(rule *CardRule) {
	ruleB, _ := json.Marshal(rule)
	a.Rule = ruleB
	a.rule = rule
}

// SetIntegralRule 设置积分规则
func (a *AccountCard) SetIntegralRule(unitIntegralAmt uint64) {
	if unitIntegralAmt < 1 {
		return
	}
	a.CanIntegral = true
	rule := a.GetRule()
	rule.UnitIntegralAmt = unitIntegralAmt
	a.setRule(rule)
	a.UpdatedAt = util.GetNow()
}

func (a *AccountCard) GetUnitIntegralAmount() uint64 {
	return a.GetRule().UnitIntegralAmt
}

// CalculateIntegral 计算积分
func (a *AccountCard) CalculateIntegral(amt uint64) uint64 {
	if amt < 1 {
		return 0
	}
	if !a.CanIntegral {
		return 0
	}
	rule := a.GetRule()
	if rule.UnitIntegralAmt == 0 {
		return 0
	}
	// 总金额/单位积分金额*积分单位
	return amt / rule.UnitIntegralAmt
}

// DisableIntegral 关闭积分功能
func (a *AccountCard) DisableIntegral() {
	a.CanIntegral = false
	rule := a.GetRule()
	rule.UnitIntegralAmt = 0
	a.setRule(rule)
	a.UpdatedAt = util.GetNow()
}

// SetDiscount 设置折扣; 百分比值
func (a *AccountCard) SetDiscount(discount uint32) {
	if discount < 1 {
		return
	}
	rule := a.GetRule()
	rule.Discount = discount
	a.setRule(rule)
	a.UpdatedAt = util.GetNow()
}

func (a *AccountCard) GetDiscount() uint32 {
	return a.GetRule().Discount
}

// SetTopupLimit 设置起充金额
func (a *AccountCard) SetTopupLimit(topupLimit uint64) {
	if topupLimit < 1 {
		return
	}
	a.CanRecharge = true
	rule := a.GetRule()
	rule.TopupLimit = topupLimit
	a.setRule(rule)
	a.UpdatedAt = util.GetNow()
}

func (a *AccountCard) GetTopupLimit() uint64 {
	return a.GetRule().TopupLimit
}

// DisableRecharge 关闭充值
func (a *AccountCard) DisableRecharge() {
	a.CanRecharge = false
	rule := a.GetRule()
	rule.TopupLimit = 0
	a.setRule(rule)
	a.UpdatedAt = util.GetNow()
}

// IsValidAmount 充值金额是否满足
func (a *AccountCard) IsValidAmount(amount uint64) bool {
	if !a.CanRecharge {
		return false
	}
	if a.GetTopupLimit() > amount {
		return false
	}
	return true
}

// Update 更新信息
func (a *AccountCard) Update(name, cover string, editor int64) {
	if name != "" {
		a.Name = name
	}
	if cover != "" {
		a.Cover = cover
	}
	a.EditorId = editor
	a.UpdatedAt = util.GetNow()
}

// CardAgg 卡信息聚合
type CardAgg struct {
	Group *AccountGroup
	Card  *AccountCard
}

func NewCardAgg(group *AccountGroup, card *AccountCard) *CardAgg {
	if group == nil || card == nil {
		return nil
	}
	return &CardAgg{
		Group: group,
		Card:  card,
	}
}
